// $Id: Persistence.cs 10 2008-02-29 15:58:02Z mcartoixa $
/*
 *  Copyright (C) 2007 Noury Solutions
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 3 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library. If not, see <http://www.gnu.org/licenses/>.
 *
 */
/*! \file
 * \brief Generic interfaces of persistent objects.
 *
 * \author $Author: mcartoixa $
 * \date $Date: 2008-02-29 16:58:02 +0100 (ven., 29 févr. 2008) $
 * \version $Revision: 10 $
 */

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using Microsoft.Practices.EnterpriseLibrary.Data;

namespace Salamanca.DataAccess.EnterpriseLibrary.Data
{



    ///////////////////////////////////////////////////////////////////////////
    ///
    /// <summary>Implementation of a persistence context.</summary>
    ///
    ///////////////////////////////////////////////////////////////////////////

    public sealed class PersistenceContext:
        IPersistenceContext
    {

        /// <summary>Constructor.</summary>
        public PersistenceContext(Database database):
            this(database, false)
        {
        }

        /// <summary>Constructor.</summary>
        public PersistenceContext(Database database, bool forceAction)
        {
            _ForceAction=forceAction;
            _Connection=database.CreateConnection();
            _Transaction=new Transaction(_Connection);

            // We own the transaction
            _DisposeTransaction=true;
        }

        /// <summary>Constructor.</summary>
        public PersistenceContext(bool forceAction, ITransaction transaction)
        {
            Debug.Assert(transaction!=null);
            if (transaction==null)
                throw new ArgumentNullException("transaction");

            _ForceAction=forceAction;
            _Transaction=transaction;
        }

        /// <summary>Finalizer.</summary>
        ~PersistenceContext()
        {
            Dispose(false);
        }

        /// <summary>Commits the operations executed in this <see cref="PersistenceContext" />.</summary>
        /// <remarks>This method does nothing more than <see cref="ITransaction.Commit" /> the current <see cref="Transaction" />.</remarks>
        public void Commit()
        {
            _Transaction.Commit();
        }

        /// <summary>Frees the resources of this instance.</summary>
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        /// <summary>Frees the resources of this instance.</summary>
        private void Dispose(bool disposing)
        {
            if (!_Disposed)
            {
                if (_DisposeTransaction)
                    // We own the transaction
                    Transaction.Dispose();
                if (_Connection!=null)
                    _Connection.Dispose();

                _Disposed=true;
            }
        }

        /// <summary>Indicates whether the persistence action is forced.</summary>
        public bool ForceAction
        {
            get
            {
                return _ForceAction;
            }
        }

        /// <summary>The <see cref="ITransaction">transaction</see> in which the persistence action is executed.</summary>
        public ITransaction Transaction
        {
            get
            {
                return _Transaction;
            }
        }

        private bool _ForceAction;
        private ITransaction _Transaction;
        private IDbConnection _Connection;
        private bool _Disposed;
        private bool _DisposeTransaction;
    }



    ///////////////////////////////////////////////////////////////////////////
    ///
    /// <summary>Implementation of a persistence provider.</summary>
    ///
    ///////////////////////////////////////////////////////////////////////////

    public sealed class PersistenceContextProvider:
        IPersistenceContextProvider
    {

        /// <summary>Initializes a new instance of the <see cref="PersistenceContextProvider" /> class.</summary>
        public PersistenceContextProvider(Database database)
        {
            _Database=database;
        }

        /// <summary>Creates a persistence context.</summary>
        public IPersistenceContext CreatePersistenceContext()
        {
            return new PersistenceContext(_Database);
        }

        /// <summary>Creates a persistence context.</summary>
        public IPersistenceContext CreatePersistenceContext(bool forceAction)
        {
            return new PersistenceContext(_Database, forceAction);
        }

        private Database _Database;
    }
}
